IoT OpenShift

Run Mosquitto MQTT Broker on Red Hat OpenShift

An MQTT Broker is a great candidate for running as a Container on something like Docker, Kubernetes, or Red Hat OpenShift. While there are several blog posts about running on Docker, I didn’t find one about OpenShift. Red Hat has a JBoss configuration for running Fuse as an MQTT Broker, but it seemed like a lot of work for a simple MQTT Broker.

So….I went out and figured out how to get Mosquitto up and running on OpenShift (Well, MiniShift, but pretty much the same thing.)

The latest and greatest version of this manifest file will be out on GitHub: https://github.com/john2exonets/OpenShift-MQTT-Mosquitto

Here is the manifest file:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mosquitto-config
data:
  mosquitto.conf: |
    # Config file for mosquitto
    user mosquitto

    retry_interval 20
    sys_interval 10
    max_inflight_messages 40
    max_queued_messages 200
    queue_qos0_messages false
    message_size_limit 0
    allow_zero_length_clientid true
    persistent_client_expiration 3m
    allow_duplicate_messages false
    autosave_interval 60
    autosave_on_changes false

    # Persistence configuration
    persistence true
    persistence_location /mqtt/data/

    # Logging
    connection_messages true
    log_dest stderr
    log_dest stdout
    log_dest file /mqtt/log/mosquitto.log
    log_type error
    log_type warning
    log_type notice
    log_type information
    log_type all
    log_type debug
    log_timestamp true

    # Listeners
    listener 1883
  mosquitto.acl: |
    # This affects access control for clients with no username.
    topic read $SYS/#

    # This affects all clients.
    pattern write $SYS/broker/connection/%c/state
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mosquitto
    openshift.io/deployment-config.name: mosquitto
  name: mosquitto
  namespace: myproject
spec:
  selector:
    matchLabels:
      app: mosquitto
  replicas: 1
  template:
    metadata:
      name: mosquitto
      labels:
        app: mosquitto
    spec:
      containers:
      - name: mostquitto
        image: toke/mosquitto
        imagePullPolicy: Always
        ports:
        - containerPort: 1883
          protocol: TCP
        resources:
          requests:
            memory: 512Mi
            cpu: 0.5
        volumeMounts:
        - mountPath: /mqtt/config
          name: mosquitto-volume-1
        - mountPath: /mqtt/data
          name: mosquitto-volume-2
        - mountPath: /mqtt/log
          name: mosquitto-volume-3
      volumes:
      - name: mosquitto-volume-1
        configMap:
          name: mosquitto-config
          items:
          - key: mosquitto.conf
            path: mosquitto.conf
      - emptyDir: {}
        name: mosquitto-volume-2
      - emptyDir: {}
        name: mosquitto-volume-3
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: mosquitto
  name: mosquitto
spec:
  ports:
  - name: mqtt
    port: 1883
  loadBalancerIP:
  selector:
    name: mosquitto
  type: LoadBalancer

There are three parts to this manifest file: a ConfigMap, a Deployment, and a Service. If I ever figure out a good NodePort, that might also be out on the GitHub distro.

The ConfigMap is the configuration files for the Mosquitto broker. They are attached as a Volume in the Deployment part of the manifest file. The Service is there to generate a NodePort that you will need to connect your MQTT clients to. This is a very simple configuration for non-SSL connections to port 1883. If you want SSL connections, then you will need to add to the mosquitto.conf file to listen to port 8883, and to define the SSL certs. You will also need to update the mosquitto.acl part of the ConfigMap to include those certs.

Starting the Mosquitto MQTT Broker

If you use the mosquitto.yaml file from the repository, starting the broker is just one command:

$ oc create -f mosquitto.yaml
configmap/mosquitto-config created
deployment.apps/mosquitto created
service/mosquitto created

At this point, you will need to know what NodePort has been assigned to Mosquitto:

$ oc get svc
NAME        TYPE           CLUSTER-IP    EXTERNAL-IP                 PORT(S)          AGE
mosquitto   LoadBalancer   172.30.5.13   172.29.175.9,172.29.175.9   1883:32342/TCP   3m

In this case, it is port 32342…that is the externally facing port. To use the MQTT broker, you just need to use the External-IP, or in this case below, the IP address of the MiniShift VM:

$ node node_modules/mqtt/mqtt.js pub -h $(minishift ip) -t "test/blatt" \
-m '{"test": "blatt"}' -p 32342 -v

This is a configuration that I use for development and testing of MQTT Security and MQTT Packet Validation. One day I will come back and write about that more once what I am working on has become public.

Related posts